clear all

use "s1 data.dta"

*pid
gen PID=pid
recode PID 1=2 2=6 3/4=4
recode PID 2=1 if pidd==1
recode PID 6=7 if pidr==1
recode PID 4=3 if pidi==1
recode PID 4=5 if pidi==2
recode PID 1/3=1 4=2 5/7=3, gen(PID3)
gen PIDext=abs(PID-4)
gen ideoext=abs(ideo-4)

gen PIDext01=(PIDext/3)
gen demimport01=(demimport-1)/4
gen repimport01=(repimport-1)/4
egen import01=rowfirst(demimport01 repimport01)
replace import01=0 if PID==4
alpha PIDext01 import01, item casewise gen(PIDstr)

*demos
recode sex 2/3=0, gen(male)
recode race 1=1 2/5=0, gen(white)

*trait aggression
recode BPAQ_1 1=6 2=5 3=4 4=3 5=2 6=1
recode BPAQ_3 1=6 2=5 3=4 4=3 5=2 6=1
recode BPAQ_4 1=6 2=5 3=4 4=3 5=2 6=1
recode BPAQ_5 1=6 2=5 3=4 4=3 5=2 6=1
alpha BPAQ*, item casewise asis gen(TraitAgg)

** reshaping **
gen RespID=_n
reshape long policy impt mc aggdv protest block yell shout threat graffiti eggs punch treatstate, i(RespID) j(scenario)

label define scenariol 1 "OR: Sanctuary" 2 "OR: Gun Storage" 3 "CA: Ethnic Studies" 4 "CA: Vaccine Mandate" 5 "OR: Emissions" 6 "TX: Abortion Ban" 7 "TX: Mask Ban" 8 "TX: Constitutional Carry" 9 "FL: CRT Ban" 10 "FL: Transgender" 11 "TX: Camping Ban", replace
label values scenario scenariol

recode policy 1=7 2=6 3=5 5=3 6=2 7=1
recode policy 1/3=1 4/7=0, gen(policydi)
gen attext=abs(policy-4)

recode protest 1/3=0 4/5=1, gen(protestdi)
recode block 1/3=0 4/5=1, gen(blockdi)
recode yell 1/3=0 4/5=1, gen(yelldi)
recode shout 1/3=0 4/5=1, gen(shoutdi)
recode threat 1/3=0 4/5=1, gen(threatdi)
recode graffiti 1/3=0 4/5=1, gen(graffitidi)
recode eggs 1/3=0 4/5=1, gen(eggsdi)
recode punch 1/3=0 4/5=1, gen(punchdi)

*mean/between measures
egen mc_mean=mean(mc) if policy<4, by(RespID)
egen attext_mean=mean(attext) if policy<4, by(RespID)
egen impt_mean=mean(impt) if policy<4, by(RespID)

*rescaling all vars to 0-1
replace mc=(mc-1)/4
replace mc_mean=(mc_mean-1)/4
replace impt=(impt-1)/4
replace impt_mean=(impt_mean-1)/4
replace attext=attext/3
replace attext_mean=attext_mean/3
replace PIDext=PIDext/3
replace TraitAgg=(TraitAgg-1)/4.25

label var mc_mean "Moral Conviction (Between)"
label var impt_mean "Importance (Between)"
label var attext_mean "Extremity (Between)"

*creating attitude intensity index
alpha mc attext impt, item casewise gen(intensity)
egen intensity_mean=mean(intensity) if policy<4, by(RespID)
label var intensity_mean "Intensity (Between)"

*mean-differenced for within-between model
gen mc_diff=mc-mc_mean
gen impt_diff=impt-impt_mean
gen attext_diff=attext-attext_mean
gen intensity_diff=intensity-intensity_mean

label var mc_diff "Moral Conviction (Within)"
label var impt_diff "Importance (Within)"
label var attext_diff "Extremity (Within)"
label var intensity_diff "Intensity (Within)"

encode treatstate, gen(treatstatenum)
replace treatstatenum=. if aggdv==.

*effect of exclusion on covariates
twoway (hist PIDext if policy<8, width(.25) color(green%30)) (hist PIDext if policy<4, width(.25) color(red%30) xlab(.125 "Independent" .375 "Leaner" .625 "Weak" .875 "Strong") xtitle("Strength of Partisan ID") legend(pos(6) order(1 "Full Sample" 2 "Effective Sample") rows(1)) saving(excl_pidext_S1.gph, replace))

twoway kdensity PIDstr if policy<8, bwidth(.15) || kdensity PIDstr if policy<4, bwidth(.15) legend(pos(6) order(1 "Full Sample" 2 "Effective Sample") rows(1)) xtitle("Partisan Strength Index") ytitle(Density) saving(excl_pidstr_S1.gph, replace)

twoway kdensity TraitAgg if policy<8, bwidth(.1) || kdensity TraitAgg if policy<4, bwidth(.1) legend(pos(6) order(1 "Full Sample" 2 "Effective Sample") rows(1)) xtitle("Trait Aggression") ytitle(Density) saving(excl_agg_S1.gph, replace)

graph combine excl_pidext_S1.gph excl_pidstr_S1.gph excl_agg_S1.gph



*descriptives 
tab policydi
tab shoutdi if policydi==1
tab eggsdi if policydi==1
tab threatdi if policydi==1
tab punchdi if policydi==1


** Figure 1 **
gen y=.
sum protestdi if policydi==1
replace y=r(mean) in 1
sum blockdi if policydi==1
replace y=r(mean) in 2
sum yelldi if policydi==1
replace y=r(mean) in 3
sum shoutdi if policydi==1
replace y=r(mean) in 4
sum eggsdi if policydi==1
replace y=r(mean) in 5
sum graffitidi if policydi==1
replace y=r(mean) in 6
sum punchdi if policydi==1
replace y=r(mean) in 7
sum threatdi if policydi==1
replace y=r(mean) in 8
gen x=_n
replace x=. if _n>8
label define actionl 1 "Protest the Governor" 2 "Block Governor's street" 3 "Yell obscenities" 4 "Shout out of restaurant" 5 "Egg the Governor" 6 "Graffiti Governor's car" 7 "Punch the Governor" 8 "Threatening messages", replace
label values x actionl

graph bar y, over(x,  label(labsize(small))) horiz ytitle("Proportion Supporting") subtitle("Support for Action (Study 1)") ylab(0(.1).7) saving(aggbyitem_S1.gph, replace)

gen aggsum=yelldi+shoutdi+eggsdi+graffitidi+punchdi+threatdi
graph bar aggsum if policydi==1, over(scenario, sort((mean) aggsum) descending label(labsize(small))) horiz ytitle("Mean Number of Aggressive Actions Supported") subtitle("Support for Aggression by Policy (Study 1)") saving(aggbypolicy_S1.gph, replace)



** models **
xtset RespID

*intensity
mixed aggdv intensity_diff intensity_mean i.scenario if policy<4, vce(cluster RespID) || RespID:
est store t1_1
lincomest intensity_diff
est store i1

*mc - alone
mixed aggdv mc_diff mc_mean i.scenario if policy<4 || RespID: , vce(cluster RespID)
est store t1_2
lincomest mc_diff
est store mc1

*mc - with both
mixed aggdv mc_diff impt_diff attext_diff mc_mean impt_mean attext_mean i.scenario if policy<4 || RespID: , vce(cluster RespID)
est store t1_3
lincomest mc_diff
est store mc3

*impt - alone
mixed aggdv impt_diff impt_mean i.scenario if policy<4 || RespID: , vce(cluster RespID)
est store t1_4
lincomest impt_diff
est store impt1

*mc - with both
mixed aggdv mc_diff impt_diff attext_diff mc_mean impt_mean attext_mean i.scenario if policy<4 || RespID: , vce(cluster RespID)
est store t1_5
lincomest impt_diff
est store impt3

*ext - alone
mixed aggdv attext_diff attext_mean i.scenario if policy<4 || RespID: , vce(cluster RespID)
est store t1_6
lincomest attext_diff
est store ext1

*ext - with both
mixed aggdv mc_diff impt_diff attext_diff mc_mean impt_mean attext_mean i.scenario if policy<4 || RespID: , vce(cluster RespID)
est store t1_7
lincomest attext_diff
est store ext3

** Figure 2 **
coefplot (mc1, aseq("Moral Conviction") swapnames) (impt1, aseq("Importance") swapnames) (ext1, aseq("Extremity") swapnames subtitle("Study 1: Single-Predictor Models") legend(off) xlab(-.2(.2).6) xline(0) saving(strength_solo.gph, replace))

coefplot (mc3, aseq("Moral Conviction") swapnames) (impt3, aseq("Importance") swapnames) (ext3, aseq("Extremity") swapnames subtitle("Study 1: Full Model") legend(off) xlab(-.2(.2).6) xline(0) saving(strength_full.gph, replace))


*alternative fixed effects models - attitude strength
xtset RespID

xtreg aggdv intensity i.scenario if policy<4, fe cluster(RespID)
est store fe_t20

xtreg aggdv mc i.scenario if policy<4, fe cluster(RespID)
est store fe_t21

xtreg aggdv impt i.scenario if policy<4, fe cluster(RespID)
est store fe_t22

xtreg aggdv attext i.scenario if policy<4, fe cluster(RespID)
est store fe_t23

xtreg aggdv mc impt attext i.scenario if policy<4, fe cluster(RespID)
est store fe_t24


** Table 2 **

*column 1
mixed aggdv PIDstr TraitAgg i.scenario if policy<4, vce(cluster RespID) || RespID:
est store t2_1

*column 4
mixed aggdv c.intensity_diff##c.PIDstr c.intensity_diff##c.TraitAgg intensity_mean i.scenario if policy<4, vce(cluster RespID) || RespID:
est store t2_4

*marginal effects
margins, dydx(TraitAgg) at(intensity_diff=(-.48 .43) PIDstr=.55)
margins, dydx(intensity_diff) at(TraitAgg=(0 1) PIDstr=.55)
margins, dydx(PIDstr) at(intensity_diff=(-.48 .43))


*figure 3
mixed aggdv c.intensity_diff##c.PIDstr c.intensity_diff##c.TraitAgg intensity_mean i.scenario if policy<4, vce(cluster RespID) || RespID:

*top left
margins, at(TraitAgg=(0 1) intensity_diff=(-.48 .43) PIDstr=.55) vsquish
marginsplot, x(TraitAgg) recast(line) recastci(rarea) ci1opts(color(%30)) ci2opts(color(%30)) xtitle(Trait Aggression) ytitle("Support for Aggression", size(small)) ylab(1(1)4) ysc(range(0.85 4)) title("") saving(TraitIntensity_intx_S1.gph, replace) legend(order(3 "Minimum Attitude Intensity" 4 "Maximum Attitude Intensity") rows(1) pos(6)) subtitle("Study 1")

*bottom left
margins, at(PIDstr=(0 1) intensity_diff=(-.48 .43) TraitAgg=.34) vsquish
marginsplot, x(PIDstr) recast(line) recastci(rarea) ci1opts(color(%30)) ci2opts(color(%30)) xtitle(Partisan Strength) ytitle("Support for Aggression", size(small)) ylab(1(1)4) ysc(range(0.85 4)) title("") saving(PIDIntensity_intx_S1.gph, replace) subtitle("Study 1")


** Table A6 - fixed effects, attitude strength

xtset RespID

xtreg aggdv intensity i.scenario if policy<4, fe vce(cluster RespID)
est store a61

xtreg aggdv mc i.scenario if policy<4, fe vce(cluster RespID)
est store a62

xtreg aggdv impt i.scenario if policy<4, fe vce(cluster RespID)
est store a63

xtreg aggdv attext i.scenario if policy<4, fe vce(cluster RespID)
est store a64

xtreg aggdv mc impt attext i.scenario if policy<4, fe vce(cluster RespID)
est store a65


** Table A7 - fixed effects, interactions
xtreg aggdv c.intensity##c.PIDstr c.intensity##c.TraitAgg i.scenario if policy<4, fe vce(cluster RespID)


